package com.atguigu.common;


import com.github.difflib.DiffUtils;
import org.apache.hadoop.shaded.org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.hadoop.shaded.org.apache.http.HttpEntity;
import org.apache.hadoop.shaded.org.apache.http.client.config.RequestConfig;
import org.apache.hadoop.shaded.org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.hadoop.shaded.org.apache.http.client.methods.HttpPost;
import org.apache.hadoop.shaded.org.apache.http.entity.StringEntity;
import org.apache.hadoop.shaded.org.apache.http.impl.client.CloseableHttpClient;
import org.apache.hadoop.shaded.org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Utils {

    public static String URL = "http://practice.atguigu.cn";
    private static final Logger LOG = LoggerFactory.getLogger(Utils.class);

    public static void delete(String path) {
        Path filePath = Paths.get(path);
        try {
            Files.delete(filePath);
        } catch (DirectoryNotEmptyException e) {
            try (Stream<Path> list = Files.list(filePath)) {
                list.map(Path::toString).forEach(Utils::delete);
                Files.delete(filePath);
            } catch (IOException ignore) {}
        } catch (IOException ignored) {}
    }

    public static DiffCounter fileDiff(String originalDirectory, String revisedDirectory) {
        List<String> original = readFiles(originalDirectory);
        List<String> revised = readFiles(revisedDirectory);

        original.sort(String::compareTo);
        revised.sort(String::compareTo);

        return new DiffCounter(DiffUtils.diff(original, revised, true));
    }

    private static List<String> readFiles(String revisedDirectory) {
        List<String> fileContent = new ArrayList<>();
        try (Stream<Path> revisedFiles = Files.list(Paths.get(revisedDirectory))) {
            revisedFiles.filter(path -> !path.getFileName().toString().startsWith("."))
                    .forEach(path -> {
                        try (TextStream textStream = new TextStream(Files.newInputStream(path))) {
                            textStream.forEach(fileContent::add);
                        } catch (IOException ignored) {}
                    });
        } catch (IOException e) {
            LOG.error(revisedDirectory + "文件夹不存在？");
        }
        return fileContent;
    }

    public static byte[] doPost(String url, String paramJson) throws IOException {
        final CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);
        // 配置请求参数实例
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        // 设置请求头
        httpPost.addHeader("Content-Type", "application/json");
        httpPost.addHeader("token", System.getenv("PROJECT_TOKEN"));
        httpPost.setEntity(new StringEntity(paramJson, StandardCharsets.UTF_8));
        try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            buffer.write(entity.getContent());
            return buffer.toByteArray();
        } finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void sendResult(Boolean result) {
        try {
            byte[] body = Utils.doPost(URL + "/query/submitV2", "{\"token\": \"" + System.getenv("PROJECT_TOKEN") + "\", \"question_id\": " + System.getenv("PROJECT_ID") + " ,\"result\":" + result + "}");
            LOG.info(new String(body, StandardCharsets.UTF_8));
            if (result) {
                // 打印成功信息
                LOG.error("解答正确，请登录" + URL + "查看排名，IDE容器将在10s后失效。");
            } else {
                LOG.error("解答有误，请检查程序");
            }
        } catch (IOException e) {
            LOG.error("由于" + e.getMessage() + "，结果发送失败，请稍后重试。");
            e.printStackTrace();
        }
    }
}
